namespace SimpleWebServices.Web.UI.Html.Elements
{
    using System;
    using System.Xml.Serialization;
    using SimpleWebServices;
    using Xunit;

    public sealed class AnchorFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<Anchor>()
                .DerivesFrom<InnerElements>()
                .IsConcreteClass()
                .IsUnsealed()
                .HasDefaultConstructor()
                .Implements<IAttributeAccesskey>()
                .Implements<IAttributeTabIndex>()
                .Implements<IXmlSerializable>()
                .XmlRoot("a")
                .Result);
        }

        [Fact]
        public void deserialize()
        {
            Anchor expected = new Anchor
            {
                Id = "id",
                Accesskey = 'a',
                Class = "class",
                Hyperlink = new Uri("http://example.com/target"),
                Language = "fr",
                Relationship = "bookmark",
                ReverseLink = "bookmark",
                TabIndex = 1,
                Title = "title",
                Elements =
                {
                    new TextString("Some text")
                }
            };

            string xml = "<a id='id' class='class' lang='fr' title='title' accesskey='a' href='http://example.com/target' rel='bookmark' rev='bookmark' tabindex='1'>Some text</a>";
            Anchor actual = xml.Deserialize<Anchor>();

            Assert.Equal<string>(expected.ToString(), actual.ToString());
        }

        [Fact]
        public void deserializeEmpty()
        {
            Assert.NotNull("<a />".Deserialize<Anchor>());
        }

        [Fact]
        public void serialize()
        {
            Anchor obj = new Anchor
            {
                Id = "id",
                Accesskey = 'a',
                Class = "class",
                Hyperlink = new Uri("http://example.com/target"),
                Language = "fr",
                Relationship = "bookmark",
                ReverseLink = "bookmark",
                TabIndex = 1,
                Title = "title",
                Elements =
                {
                    new TextString("Some text")
                }
            };

            string xpath = "1=count(/a[@accesskey='a'][@href='http://example.com/target'][@rel='bookmark'][@rev='bookmark'][@tabindex='1'][@id='id'][@class='class'][@lang='fr'][@title='title'][text()='Some text'])";

            Assert.True((bool)obj.Serialize().CreateNavigator().Evaluate(xpath));
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new Anchor());
        }

        [Fact]
        public void ctor_stringAbsolute_string()
        {
            Assert.NotNull(new Anchor("http://example.com/", "bookmark"));
        }

        [Fact]
        public void ctor_stringRelative_string()
        {
            Assert.NotNull(new Anchor("/", "bookmark"));
        }

        [Fact]
        public void ctor_stringNull_string()
        {
            Assert.NotNull(new Anchor(null as string, "bookmark"));
        }

        [Fact]
        public void ctor_UriAbsolute_string()
        {
            Assert.NotNull(new Anchor(new Uri("http://example.com/"), "bookmark"));
        }

        [Fact]
        public void ctor_UriRelative_string()
        {
            Assert.NotNull(new Anchor(new Uri("/", UriKind.Relative), "bookmark"));
        }

        [Fact]
        public void ctor_UriNull_string()
        {
            Assert.NotNull(new Anchor(null as Uri, "bookmark"));
        }

        [Fact]
        public void ctor_Uri_stringEmpty()
        {
            Assert.NotNull(new Anchor(new Uri("http://example.com/"), string.Empty));
        }

        [Fact]
        public void ctor_Uri_stringNull()
        {
            Assert.NotNull(new Anchor(new Uri("http://example.com/"), null as string));
        }

        [Fact]
        public void prop_Accesskey()
        {
            Assert.True(new PropertyExpectations(typeof(Anchor).GetProperty("Accesskey"))
                .IsAutoProperty<char?>()
                .Result);
        }

        [Fact]
        public void prop_Hyperlink()
        {
            Assert.True(new PropertyExpectations(typeof(Anchor).GetProperty("Hyperlink"))
                .IsAutoProperty<Uri>()
                .Result);
        }

        [Fact]
        public void prop_Relationship()
        {
            Assert.True(new PropertyExpectations(typeof(Anchor).GetProperty("Relationship"))
                .IsAutoProperty<string>()
                .Result);
        }

        [Fact]
        public void prop_ReverseLink()
        {
            Assert.True(new PropertyExpectations(typeof(Anchor).GetProperty("ReverseLink"))
                .IsAutoProperty<string>()
                .Result);
        }

        [Fact]
        public void prop_TabIndex()
        {
            Assert.True(new PropertyExpectations(typeof(Anchor).GetProperty("TabIndex"))
                .IsAutoProperty<int?>()
                .Result);
        }

        [Fact]
        public void prop_Title()
        {
            Assert.True(new PropertyExpectations(typeof(Anchor).GetProperty("Title"))
                .IsAutoProperty<char?>()
                .Result);
        }

        [Fact]
        public void op_Deserialize_string_string_string()
        {
            Anchor expected = new Anchor
            {
                Id = "id",
                Accesskey = 'a',
                Class = "class",
                Hyperlink = new Uri("http://example.com/target"),
                Language = "fr",
                Relationship = "bookmark",
                ReverseLink = "bookmark",
                TabIndex = 1,
                Title = "title",
                Elements =
                {
                    new TextString("Some text")
                }
            };

            string xml = "<a id='id' class='class' lang='fr' title='title' accesskey='a' href='http://example.com/target' rel='bookmark' rev='bookmark' tabindex='1'>Some text</a>";
            Anchor actual = new Anchor().Deserialize("a", null, xml) as Anchor;

            Assert.Equal<string>(expected.ToString(), actual.ToString());
        }
    }
}